package org.javahispano.javacup.tacticas_aceptadas.rudeboy.chimbitaFinal;

import java.util.ArrayList;
import java.util.List;

import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.modelo.ComandoIrA;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.TacticaDetalle;

public class ChimbitaTacticaFinal implements Tactica {

	Posicion alineacion5[] = new Posicion[] { new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(16.405594405594407, -26.606334841628957), new Posicion(5.706293706293707, -31.83257918552036),
			new Posicion(-7.37062937062937, -24.468325791855204),
			new Posicion(-18.06993006993007, -27.794117647058822),
			new Posicion(-19.734265734265733, -4.276018099547511),
			new Posicion(-25.44055944055944, -15.678733031674208),
			new Posicion(24.251748251748253, -15.678733031674208),
			new Posicion(0.23776223776223776, -0.23755656108597287),
			new Posicion(15.454545454545453, -2.8506787330316743),
			new Posicion(-0.4755244755244755, -9.502262443438914) };

	Posicion alineacion6[] = new Posicion[] { new Posicion(0.2595419847328244, -50.41044776119403),
			new Posicion(15.454545454545453, -32.782805429864254),
			new Posicion(4.9930069930069925, -32.30769230769231),
			new Posicion(-7.608391608391608, -33.257918552036195),
			new Posicion(-16.405594405594407, -31.83257918552036),
			new Posicion(-8.797202797202797, -6.176470588235294), new Posicion(-20.20979020979021, -17.34162895927602),
			new Posicion(18.78321678321678, -17.816742081447966), new Posicion(10.223776223776223, -5.226244343891403),
			new Posicion(3.804195804195804, -9.739819004524888), new Posicion(-1.902097902097902, -10.452488687782806) };

	public static TacticaDetalle detalle = new Tactica16PuntosDetalleImpl();

	Posicion3D balonPasado = new Posicion3D(new Posicion(), 0);
	double alturaAnterior = 0;
	int porteroRival = -1;
	int conteoSaque = 0;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.javahispano.javacup.modelo.Tactica#ejecutar(org.javahispano.javacup.modelo.SituacionPartido)
	 */
	public List<Comando> ejecutar(SituacionPartido sp) {
		List<Comando> comdAux = new ArrayList<Comando>();
		// Determino el indice del portero rival
		if (porteroRival < 0) {
			porteroRival = Ayudativo.getArquero(sp.detalleJugadoresRivales());
		}
		if (sp.saco()) {
			comdAux.clear();
			int idxMasCercano = sp.balon().indiceMasCercano(sp.misJugadores());
			if (sp.balon().getY() < 0) {
				for (int h = 0; h < 11; h++) {
					if (idxMasCercano != h) {
						comdAux.add(new ComandoIrA(h, alineacion5[h]));
					}
				}
			}
			comdAux.add(new ComandoIrA(idxMasCercano, sp.balon()));
			if (conteoSaque > 30 && (idxMasCercano == 0 || cracks[idxMasCercano].puedoPatear(sp))) {
				if (idxMasCercano > 0) {
					comdAux.addAll(cracks[idxMasCercano].mejorPosicionPasar(sp, porteroRival));
				} else {
					comdAux.add(new ComandoGolpearBalon(idxMasCercano, sp.balon().getX() > 0 ? Ayudativo.E
							: Ayudativo.D, 1, 45));
				}
			}
			conteoSaque++;
		} else {
			Posicion3D proxBalon = Ayudativo.getSiguientePuntoEnTrayectoria(balonPasado, new Posicion3D(sp.balon(), sp
					.alturaBalon()), -1);
			conteoSaque = 0;
			// determino si el balon est� en poder de un jugagador mio
			int mioAlBalon = Ayudativo.posicionMia(proxBalon.pos2d, sp);
			int jugadoresAlBalon = 0;
			int[] cercanosAlBalon = sp.balon().indicesMasCercanos(sp.misJugadores());// contendra
			// a
			// mis
			// jugadores
			// en
			// orden
			// de
			// cercania
			// al
			// bal�n;
			if (mioAlBalon > 0) {
				// mi jugador abandona su marca para ir por el bal�n dado que es
				// el
				// m�s cercano
				comdAux.add(new ComandoIrA(mioAlBalon, proxBalon.pos2d));
				ChimbitaJugador.marcadosRival.remove(cracks[mioAlBalon].marcando);
				cracks[mioAlBalon].marcando = -1;
				jugadoresAlBalon++;
			}
			for (int h = 0; h < cercanosAlBalon.length; h++) {
				int indiceActual = cercanosAlBalon[h];
				if (indiceActual == 0 || indiceActual == mioAlBalon) {
					continue;// el arquero y el jugador que busca el bal�n,
					// tiene
					// otra l�gica
				}
				if (jugadoresAlBalon < 2 && cracks[indiceActual].balonEnMiCuadrante(sp.balon())) {
					// si el balon est� en mi cuadrante y no hay m�s de 1
					// jugador mio persiguiendolo, entonces voy al bal�n y
					// libero
					// mi marca
					comdAux.add(new ComandoIrA(cracks[indiceActual].idx, proxBalon.pos2d));
					ChimbitaJugador.marcadosRival.remove(cracks[indiceActual].marcando);
					cracks[indiceActual].marcando = -1;
					jugadoresAlBalon++;
				} else {
					// si no ataco el bal�n, marco a alg�n rival
					int marcarA = cracks[indiceActual].aQuienMarco(sp);
					cracks[indiceActual].marcando = marcarA;
					if (marcarA < 0 || sp.rivales()[marcarA].getY() > 0d) {
						// si no hay alg�n jugador para marcar y el jugador a
						// marcar
						// no est� en mi mitad de cancha ,
						// mi jugador intenta
						// desmarcarse y situarse en la mejor posici�n para
						// recibir
						// un pase
						comdAux.add(new ComandoIrA(cracks[indiceActual].idx, cracks[indiceActual].mejorPosicionIr(sp
								.balon(), balonPasado.pos2d)));
					} else {
						// marca hombre a hombre
						double direccionMarca = sp.rivales()[marcarA].angulo(Constantes.centroArcoInf);
						comdAux.add(new ComandoIrA(cracks[indiceActual].idx, sp.rivales()[marcarA].moverAngulo(
								direccionMarca, 2.4d)));
					}
				}
			}
			for (int s = 0; s < sp.puedenRematar().length; s++) {
				// todos mis jugadores que pueden rematar reciben la orden de
				// hacerlo
				int idxAct = sp.puedenRematar()[s];
				if (idxAct == 0) {
					// si remata mi arquero debo despejar
					comdAux.add(new ComandoGolpearBalon(idxAct, sp.balon().getX() > 0 ? Ayudativo.E : Ayudativo.D, 1,
							35));
				} else {
					comdAux.addAll(cracks[idxAct].mejorPosicionPasar(sp, porteroRival));
				}
			}
			for (ChimbitaJugador jug : cracks) {
				if (jug != null) {
					// jugadores picando al vacio...
					Posicion ir = jug.buscarBalon();
					if (ir != null) {
						comdAux.add(new ComandoIrA(jug.idx, proxBalon.pos2d));
					}
				}
			}
			// ubico al arquero en su mejor posicion
			comdAux.add(new ComandoIrA(0, Ayudativo.getPosicionArquero(sp.balon(), balonPasado.pos2d)));
		}
		balonPasado.altura = sp.alturaBalon();
		balonPasado.pos2d = sp.balon();
		return Ayudativo.getComandosDepurado(comdAux);
	}

	public static ChimbitaJugador[] cracks = new ChimbitaJugador[] {
			null,// el arquero no se cuenta...
			new ChimbitaJugador(detalle.getJugadores()[1], new Posicion(Constantes.LARGO_AREA_GRANDE / 2,
					Constantes.cornerInfIzq.getY() + Constantes.ANCHO_AREA_GRANDE), new Posicion(
					Constantes.LARGO_AREA_GRANDE / -2, Constantes.cornerInfIzq.getY() + 3), 1, new Posicion(0,
					Constantes.cornerInfIzq.getY() + Constantes.DISTANCIA_PENAL), new Posicion(0,
					Constantes.cornerInfIzq.getY() + Constantes.DISTANCIA_PENAL), new Posicion[] { Ayudativo.I,
					Ayudativo.J, Ayudativo.D, Ayudativo.E, Ayudativo.F, Ayudativo.G }, new int[] { 2, 3, 4, 5, 6, 7, 8,
					9, 10 }, false),
			new ChimbitaJugador(detalle.getJugadores()[2], new Posicion(Constantes.LARGO_AREA_CHICA / 2,
					-Constantes.ANCHO_AREA_GRANDE),
			// new Posicion(-Constantes.LARGO_AREA_GRANDE / 2,
			// Constantes.cornerInfIzq.getY() + 2)
					new Posicion(Constantes.cornerInfIzq.getX(), Constantes.cornerInfIzq.getY() + 2), 2, new Posicion(
							-Constantes.LARGO_AREA_CHICA / 2, Constantes.centroArcoInf.getY()
									+ Constantes.ANCHO_AREA_GRANDE), new Posicion(-Constantes.LARGO_AREA_CHICA / 2,
							Constantes.centroArcoInf.getY() + Constantes.ANCHO_AREA_GRANDE + 10), new Posicion[] {
							Ayudativo.I, Ayudativo.J, Ayudativo.D, Ayudativo.E, Ayudativo.F, Ayudativo.G }, new int[] {
							3, 4, 5, 6, 7, 8, 9, 10, 1 }, false),
			new ChimbitaJugador(detalle.getJugadores()[3],
			// new Posicion(Constantes.LARGO_AREA_GRANDE / 2,
			// -Constantes.ANCHO_AREA_GRANDE),
					new Posicion(Constantes.cornerSupDer.getX(), -Constantes.ANCHO_AREA_GRANDE), new Posicion(
							-Constantes.LARGO_AREA_CHICA / 2, Constantes.cornerInfIzq.getY() + 2), 3, new Posicion(
							Constantes.LARGO_AREA_CHICA / 2, Constantes.centroArcoInf.getY()
									+ Constantes.ANCHO_AREA_GRANDE), new Posicion(Constantes.LARGO_AREA_CHICA / 2,
							Constantes.centroArcoInf.getY() + Constantes.ANCHO_AREA_GRANDE + 10), new Posicion[] {
							Ayudativo.E, Ayudativo.D, Ayudativo.G, Ayudativo.F, Ayudativo.I, Ayudativo.J, }, new int[] {
							2, 4, 5, 6, 7, 8, 9, 10, 1 }, false),
			new ChimbitaJugador(detalle.getJugadores()[4], new Posicion(Constantes.cornerInfDer.getX(),
					-Constantes.ANCHO_AREA_GRANDE), Constantes.cornerInfIzq, 4, new Posicion(
					Constantes.LARGO_AREA_GRANDE / 2, Constantes.centroArcoInf.getY() + Constantes.ANCHO_AREA_GRANDE),
					new Posicion(Constantes.LARGO_AREA_GRANDE / 2, Constantes.centroArcoInf.getY()
							+ Constantes.ANCHO_AREA_GRANDE + 10), new Posicion[] { Ayudativo.E, Ayudativo.D,
							Ayudativo.G, Ayudativo.F, Ayudativo.I, Ayudativo.J, }, new int[] { 2, 3, 5, 6, 7, 8, 9, 10,
							1 }, false),
			new ChimbitaJugador(detalle.getJugadores()[5], new Posicion(Constantes.LARGO_AREA_CHICA / 2,
					Constantes.ANCHO_AREA_GRANDE), new Posicion(Constantes.cornerInfIzq.getX(), Constantes.cornerInfIzq
					.getY()
					+ Constantes.ANCHO_AREA_GRANDE), 5, Ayudativo.F, Ayudativo.F, new Posicion[] { Ayudativo.F,
					Ayudativo.G, Ayudativo.D, Ayudativo.E, Ayudativo.I, Ayudativo.J, }, new int[] { 2, 3, 4, 6, 7, 8,
					9, 10, 1 }, false),
			new ChimbitaJugador(detalle.getJugadores()[6], new Posicion(Constantes.cornerInfDer.getX(),
					Constantes.ANCHO_AREA_GRANDE), new Posicion(-Constantes.LARGO_AREA_CHICA / 2,
					Constantes.cornerInfIzq.getY() + Constantes.ANCHO_AREA_GRANDE), 6, Ayudativo.G, Ayudativo.G,
					new Posicion[] { Ayudativo.G, Ayudativo.F, Ayudativo.E, Ayudativo.D, Ayudativo.I, Ayudativo.J, },
					new int[] { 2, 3, 4, 5, 7, 8, 9, 10, 1 }, false),
			new ChimbitaJugador(detalle.getJugadores()[7], Constantes.cornerSupDer,
					// new Posicion(Constantes.cornerSupDer.getX(),2 *
					// Constantes.ANCHO_AREA_GRANDE),
					new Posicion(Constantes.cornerSupIzq.getX(), -(1.5) * Constantes.ANCHO_AREA_GRANDE), 7,
					Ayudativo.I, Ayudativo.I, new Posicion[] { Ayudativo.HL, Ayudativo.HR, Ayudativo.H, Ayudativo.F,
							Ayudativo.G, Ayudativo.J, Ayudativo.I, Ayudativo.D, Ayudativo.E }, new int[] { 5, 6, 8, 9,
							10 }, false),
			new ChimbitaJugador(detalle.getJugadores()[8], new Posicion(Constantes.LARGO_AREA_CHICA / 2,
					Constantes.cornerSupDer.getY()), new Posicion(Constantes.cornerInfIzq.getX(), 0), 8, Ayudativo.F,
					Ayudativo.F, 
					new Posicion[] { Ayudativo.J,  Ayudativo.H }, new int[] { 5, 6, 7, 9, 10 }, true),
			new ChimbitaJugador(detalle.getJugadores()[9], Constantes.cornerSupDer, new Posicion(
					-Constantes.LARGO_AREA_CHICA / 2, 0), 9, Ayudativo.G, Ayudativo.G, 
					new Posicion[] {Ayudativo.J, Ayudativo.H }, 
					new int[] { 5, 6, 7, 8, 10 }, true),
			new ChimbitaJugador(detalle.getJugadores()[10], Constantes.cornerSupDer, new Posicion(
					Constantes.cornerInfIzq.getX(), Constantes.ANCHO_AREA_GRANDE), 10, new Posicion(0,
					Constantes.ANCHO_AREA_GRANDE), Constantes.penalSup, new Posicion[] {}, new int[] { 8, 9}, false) };

	public TacticaDetalle getDetalle() {
		return detalle;
	}

	public Posicion[] getPosicionSaca(SituacionPartido sp) {
		return alineacion5;
	}

	public Posicion[] getPosicionRecive(SituacionPartido sp) {
		return alineacion6;
	}

}
